package com.db.service.bank;

import com.db.domain.bank.*;
import com.db.exceptions.BankException;
import com.db.exceptions.NotEnoughFundsException;
import com.db.service.email.EmailNotificationListener;
import com.db.service.email.EmailService;

import java.io.*;
import java.util.Random;

public class BankApplication {
    private static final BankService bankService = new BankService();
    private static Bank bank = new Bank();

    public static void main(String[] args) {
        EmailService emailService = new EmailService();
        emailService.start();
        bank.addListener(new EmailNotificationListener(emailService));
        if (args.length < 2) {
            randomInitialization();
        } else {
            switch (args[0]) {
                case "-loadfeed" : feedFileInitialization(args[1]); break;
                case "-loadbank" : bank = bankService.readBank(args[1]); break;
            }
        }
        if (args.length > 2 && args[2].equals("-server")) {
            startServer();
        }
        emailService.close();
        try {
            bank.addClient(new Client("name", Gender.MALE, createRandomAccount(2)));
        } catch (BankException e) {
            System.out.println(e.getMessage());
        }
    }

    private static void startServer() {
        BankServer bankServer = new BankServer();
        bankServer.startServer();
    }

    private static void feedFileInitialization(String path) {
        try (BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(new FileInputStream(new File(path))))) {
            String line;
            while((line = bufferedReader.readLine()) != null) {
                Client client = ClientParser.parseLineToClient(line);
                try {
                    bankService.addClient(bank, client);
                } catch (BankException e) {
                    System.err.println(e.getMessage());
                }
            }
        } catch (IOException e) {
            System.err.println(e.toString());
        }
    }

    private static void randomInitialization(){
        for (int i=0; i<10; i++) {
            Account account = createRandomAccount(i);
            Client client = new Client(Integer.toString(i), i%2 == 0 ? Gender.MALE : Gender.FEMALE, account);
            try {
                bankService.addClient(bank, client);
            } catch (BankException e) {
                System.err.println(e.getMessage());
            }
        }
    }

    private static Account createRandomAccount(int i) {
        return i % 2 == 0 ? (new SavingAccount(1000 * i)) : new CheckingAccount(1000 * i, 100 * i);
    }

    public static void modifyBank() throws NotEnoughFundsException {
        Random r = new Random();
        for (Client client : bank.getClients()) {
            if(client == null) return;
            if (r.nextBoolean()) {
                if (r.nextBoolean()) {
                    client.getAccount().deposit(100);
                } else {
                    client.getAccount().withdraw(200);
                }
            }
        }
    }

    public static String getBalances() {
        StringBuilder sb = new StringBuilder();
        for (Client client : bank.getClients()) {
            if(client == null) break;
            sb.append(client.getClientSalutation()).append(" balance ").append(client.getAccount().getBalance()).append("\n");
        }
        return sb.toString();
    }

    public static String getCountOfClients() {
        int i = 0;
        for(Client client : bank.getClients()) {
            if(client == null) break;
            i++;
        }
        return Integer.toUnsignedString(i);
    }

}
